<script setup lang="ts">
import type { ConditionField, ICondition, Option } from './typing'
import { NInput } from 'naive-ui'
import { computed, h } from 'vue'

const fields = inject<ConditionField[]>('fields', [])
const defaultOperations = inject<Option[]>('defaultOperations', [])

const model = defineModel<ICondition>('value', { default: null })

function handleFieldChange() {
  model.value.value = undefined
}

function renderComponent(key: string | undefined) {
  const field = fields.find(f => f.key === key)
  const component = field?.component || NInput

  return h(component, {
    'class': 'condition__value',
    'size': 'small',
    'value': model.value?.value,
    'onUpdate:value': (val: any) => {
      model.value.value = val
    },
    ...field,
    ...field?.props?.(model.value),
  }, field?.slot)
}

const operatorOptions = computed<Option[]>(() => {
  const field = fields.find(f => f.key === model.value.key)
  return field?.operations || defaultOperations
})
</script>

<template>
  <div class="condition">
    <!-- 字段选择 -->
    <n-select
      v-model:value="model.key"
      :options="fields?.map(f => ({ label: f.label, value: f.key }))"
      class="condition__field"
      size="small"
      placeholder="字段"
      @update:value="handleFieldChange"
    />
    <!-- 操作符选择 -->
    <n-select
      v-model:value="model.operator"
      :options="(operatorOptions as any)"
      class="condition__operator"
      size="small"
      placeholder="操作符"
    />
    <!-- 值输入，根据字段类型动态渲染组件 -->
    <component :is="renderComponent(model.key)" />
  </div>
</template>

<style scoped>
.condition {
  display: flex;
  align-items: center;
  gap: 8px;
}
.condition__field,
.condition__operator,
.condition__value {
  min-width: 200px;
}
</style>
